#include "MathUtility.h"
#include <ctime>
#include <cstdlib>

namespace Engine
{
	static bool seeded = false;

	int Random(int max)
	{
		if(!seeded)
		{
			seeded = true;
			std::srand((unsigned)time(0)); 
		}
	
		return (std::rand()% max) + 1;
	}

	float Random(float max)
	{
		if(!seeded)
		{
			seeded = true;
			std::srand((unsigned)time(0)); 
		}

		return (float) rand() / ((float)RAND_MAX / max);
	}

	bool Random()
	{
		if(!seeded)
		{
			seeded = true;
			std::srand((unsigned)time(0)); 
		}

		return Random(9) > 4 ? true : false;
	}

	float RandomBinomial(float max)
	{
		if(!seeded)
		{
			seeded = true;
			std::srand((unsigned)time(0));
		}

		return Random(max) - Random(max);
	}

	float RadToDeg(float rad)
	{
		return (rad *  (180.f / static_cast <float>(M_PI)));
	}
	
	float DegToRad(float deg)
	{
		return (deg * (static_cast <float>(M_PI) / 180.0f));
	}
	
	float VecToRad(const Vec3& vec)
	{
		return std::atan2(vec.x, vec.z);
	}
	
	Vec3 RadToVec(float angle)
	{
		return Vec3(std::sin(DegToRad(angle)), 0.0f, std::cos(DegToRad(angle)));
	}

	float Mod(float x, float y)
	{
	    if (0 == y)
	        return x;
	
	    return x - y * floor(x / y);
	}

	float MapToPiRange(float rad)
	{
		return Mod(rad + (float)M_PI, (float)M_PI * 2) - (float)M_PI;
	}

    float ScalarRandom(	const float initial, 
						const float speed,
						const float min,
						const float max)
    {
        const float next = initial + (((Random(max) * 2) - 1) * speed);
       
		if (next < min) return min;
        if (next > max) return max;

        return next;
    }
}